1 /* 2 * To compile this file into the proper files: 3 * rpcgen -C -N nfs.x 4 * rpcgen -C -N -m nfs.x > programs.c 5 * rpcgen -C -N -s tcp nfs.x > run_example.c 6 * rpcgen -C -N -Ss nfs.x > server_template.c 7 * rm nfs_clnt.c nfs_svc.c 8 * mv nfs_xdr.c xdr.c 9 */ 10 11 const PROGRAM = 100003; 12 const VERSION = 3; 13 const NFS3_FHSIZE = 64; 14 const NFS3_COOKIEVERFSIZE = 8; 15 const NFS3_CREATEVERFSIZE = 8; 16 const NFS3_WRITEVERFSIZE = 8; 17 18 %#if defined(HAVE_XDR_U_INT64_T) 19 %#define xdr_uint64_t xdr_u_int64_t 20 %#elif !defined(HAVE_XDR_UINT64_T) 21 %#if defined(HAVE_XDR_U_HYPER) 22 %#define xdr_uint64_t xdr_u_hyper 23 %#define xdr_int64_t xdr_hyper 24 %#elif defined(HAVE_XDR_U_LONGLONG_T) 25 %#define xdr_uint64_t xdr_u_longlong_t 26 %#define xdr_int64_t xdr_longlong_t 27 %#endif 28 %#endif 29 30 typedef uint64_t uint64; 31 typedef int64_t int64; 32 typedef unsigned long uint32; 33 typedef long int32; 34 typedef string filename3<>; 35 typedef string nfspath3<>; 36 typedef uint64 fileid3; 37 typedef uint64 cookie3; 38 typedef opaque cookieverf3[NFS3_COOKIEVERFSIZE]; 39 typedef opaque createverf3[NFS3_CREATEVERFSIZE]; 40 typedef opaque writeverf3[NFS3_WRITEVERFSIZE]; 41 typedef uint32 uid3; 42 typedef uint32 gid3; 43 typedef uint64 size3; 44 typedef uint64 offset3; 45 typedef uint32 mode3; 46 typedef uint32 count3; 47 48 enum nfsstat3 { 49 NFS3_OK = 0, 50 NFS3ERR_PERM = 1, 51 NFS3ERR_NOENT = 2, 52 NFS3ERR_IO = 5, 53 NFS3ERR_NXIO = 6, 54 NFS3ERR_ACCES = 13, 55 NFS3ERR_EXIST = 17, 56 NFS3ERR_XDEV = 18, 57 NFS3ERR_NODEV = 19, 58 NFS3ERR_NOTDIR = 20, 59 NFS3ERR_ISDIR = 21, 60 NFS3ERR_INVAL = 22, 61 NFS3ERR_FBIG = 27, 62 NFS3ERR_NOSPC = 28, 63 NFS3ERR_ROFS = 30, 64 NFS3ERR_MLINK = 31, 65 NFS3ERR_NAMETOOLONG = 63, 66 NFS3ERR_NOTEMPTY = 66, 67 NFS3ERR_DQUOT = 69, 68 NFS3ERR_STALE = 70, 69 NFS3ERR_REMOTE = 71, 70 NFS3ERR_BADHANDLE = 10001, 71 72 NFS3ERR_NOT_SYNC = 10002, 73 NFS3ERR_BAD_COOKIE = 10003, 74 NFS3ERR_NOTSUPP = 10004, 75 NFS3ERR_TOOSMALL = 10005, 76 NFS3ERR_SERVERFAULT = 10006, 77 NFS3ERR_BADTYPE = 10007, 78 NFS3ERR_JUKEBOX = 10008 79 }; 80 81 enum ftype3 { 82 NF3REG = 1, 83 NF3DIR = 2, 84 NF3BLK = 3, 85 NF3CHR = 4, 86 NF3LNK = 5, 87 NF3SOCK = 6, 88 NF3FIFO = 7 89 }; 90 91 struct specdata3 { 92 uint32 specdata1; 93 uint32 specdata2; 94 }; 95 96 struct nfs_fh3 { 97 opaque data<NFS3_FHSIZE>; 98 }; 99 100 struct nfstime3 { 101 uint32 seconds; 102 uint32 nseconds; 103 }; 104 105 struct fattr3 { 106 ftype3 type; 107 mode3 mode; 108 uint32 nlink; 109 uid3 uid; 110 gid3 gid; 111 size3 size; 112 size3 used; 113 specdata3 rdev; 114 uint64 fsid; 115 fileid3 fileid; 116 nfstime3 atime; 117 nfstime3 mtime; 118 nfstime3 ctime; 119 }; 120 121 union post_op_attr switch (bool attributes_follow) { 122 case TRUE: 123 fattr3 attributes; 124 case FALSE: 125 void; 126 }; 127 128 struct wcc_attr { 129 size3 size; 130 nfstime3 mtime; 131 nfstime3 ctime; 132 }; 133 134 union pre_op_attr switch (bool attributes_follow) { 135 case TRUE: 136 wcc_attr attributes; 137 case FALSE: 138 void; 139 }; 140 141 struct wcc_data { 142 pre_op_attr before; 143 post_op_attr after; 144 }; 145 146 union post_op_fh3 switch (bool handle_follows) { 147 case TRUE: 148 nfs_fh3 handle; 149 case FALSE: 150 void; 151 }; 152 153 enum time_how { 154 DONT_CHANGE = 0, 155 SET_TO_SERVER_TIME = 1, 156 SET_TO_CLIENT_TIME = 2 157 }; 158 159 union set_mode3 switch (bool set_it) { 160 case TRUE: 161 mode3 mode; 162 default: 163 void; 164 }; 165 166 union set_uid3 switch (bool set_it) { 167 case TRUE: 168 uid3 uid; 169 default: 170 void; 171 }; 172 173 union set_gid3 switch (bool set_it) { 174 case TRUE: 175 gid3 gid; 176 default: 177 void; 178 }; 179 180 union set_size3 switch (bool set_it) { 181 case TRUE: 182 size3 size; 183 default: 184 void; 185 }; 186 187 union set_atime switch (time_how set_it) { 188 case SET_TO_CLIENT_TIME: 189 nfstime3 atime; 190 default: 191 void; 192 }; 193 194 union set_mtime switch (time_how set_it) { 195 case SET_TO_CLIENT_TIME: 196 nfstime3 mtime; 197 default: 198 void; 199 }; 200 201 struct sattr3 { 202 set_mode3 mode; 203 set_uid3 uid; 204 set_gid3 gid; 205 set_size3 size; 206 set_atime atime; 207 set_mtime mtime; 208 209 }; 210 211 struct diropargs3 { 212 nfs_fh3 dir; 213 filename3 name; 214 }; 215 216 217 program NFS_PROGRAM { 218 version NFS_V3 { 219 220 void 221 NFSPROC3_NULL(void) = 0; 222 223 GETATTR3res 224 NFSPROC3_GETATTR(GETATTR3args) = 1; 225 226 SETATTR3res 227 NFSPROC3_SETATTR(SETATTR3args) = 2; 228 229 LOOKUP3res 230 NFSPROC3_LOOKUP(LOOKUP3args) = 3; 231 232 ACCESS3res 233 NFSPROC3_ACCESS(ACCESS3args) = 4; 234 235 READLINK3res 236 NFSPROC3_READLINK(READLINK3args) = 5; 237 238 READ3res 239 NFSPROC3_READ(READ3args) = 6; 240 241 WRITE3res 242 NFSPROC3_WRITE(WRITE3args) = 7; 243 244 CREATE3res 245 NFSPROC3_CREATE(CREATE3args) = 8; 246 247 MKDIR3res 248 NFSPROC3_MKDIR(MKDIR3args) = 9; 249 250 SYMLINK3res 251 NFSPROC3_SYMLINK(SYMLINK3args) = 10; 252 253 MKNOD3res 254 NFSPROC3_MKNOD(MKNOD3args) = 11; 255 256 REMOVE3res 257 NFSPROC3_REMOVE(REMOVE3args) = 12; 258 259 RMDIR3res 260 NFSPROC3_RMDIR(RMDIR3args) = 13; 261 262 RENAME3res 263 NFSPROC3_RENAME(RENAME3args) = 14; 264 265 LINK3res 266 NFSPROC3_LINK(LINK3args) = 15; 267 268 READDIR3res 269 NFSPROC3_READDIR(READDIR3args) = 16; 270 271 READDIRPLUS3res 272 NFSPROC3_READDIRPLUS(READDIRPLUS3args) = 17; 273 274 FSSTAT3res 275 NFSPROC3_FSSTAT(FSSTAT3args) = 18; 276 277 FSINFO3res 278 NFSPROC3_FSINFO(FSINFO3args) = 19; 279 280 PATHCONF3res 281 NFSPROC3_PATHCONF(PATHCONF3args) = 20; 282 283 COMMIT3res 284 NFSPROC3_COMMIT(COMMIT3args) = 21; 285 286 } = 3; 287 } = 100003; 288 289 struct GETATTR3args { 290 nfs_fh3 object; 291 }; 292 293 struct GETATTR3resok { 294 fattr3 obj_attributes; 295 }; 296 297 union GETATTR3res switch (nfsstat3 status) { 298 case NFS3_OK: 299 GETATTR3resok resok; 300 default: 301 void; 302 }; 303 304 union sattrguard3 switch (bool check) { 305 case TRUE: 306 nfstime3 obj_ctime; 307 case FALSE: 308 void; 309 }; 310 311 struct SETATTR3args { 312 nfs_fh3 object; 313 sattr3 new_attributes; 314 sattrguard3 guard; 315 }; 316 317 struct SETATTR3resok { 318 wcc_data obj_wcc; 319 }; 320 321 struct SETATTR3resfail { 322 wcc_data obj_wcc; 323 }; 324 325 union SETATTR3res switch (nfsstat3 status) { 326 case NFS3_OK: 327 SETATTR3resok resok; 328 default: 329 SETATTR3resfail resfail; 330 }; 331 332 struct LOOKUP3args { 333 diropargs3 what; 334 }; 335 336 struct LOOKUP3resok { 337 nfs_fh3 object; 338 post_op_attr obj_attributes; 339 post_op_attr dir_attributes; 340 }; 341 342 struct LOOKUP3resfail { 343 post_op_attr dir_attributes; 344 }; 345 346 union LOOKUP3res switch (nfsstat3 status) { 347 case NFS3_OK: 348 LOOKUP3resok resok; 349 default: 350 LOOKUP3resfail resfail; 351 }; 352 353 354 const ACCESS3_READ = 0x0001; 355 const ACCESS3_LOOKUP = 0x0002; 356 const ACCESS3_MODIFY = 0x0004; 357 const ACCESS3_EXTEND = 0x0008; 358 const ACCESS3_DELETE = 0x0010; 359 const ACCESS3_EXECUTE = 0x0020; 360 361 struct ACCESS3args { 362 nfs_fh3 object; 363 uint32 access; 364 }; 365 366 struct ACCESS3resok { 367 post_op_attr obj_attributes; 368 uint32 access; 369 }; 370 371 struct ACCESS3resfail { 372 post_op_attr obj_attributes; 373 }; 374 375 union ACCESS3res switch (nfsstat3 status) { 376 case NFS3_OK: 377 ACCESS3resok resok; 378 default: 379 ACCESS3resfail resfail; 380 }; 381 382 struct READLINK3args { 383 nfs_fh3 symlink; 384 }; 385 386 struct READLINK3resok { 387 post_op_attr symlink_attributes; 388 nfspath3 data; 389 }; 390 391 struct READLINK3resfail { 392 post_op_attr symlink_attributes; 393 }; 394 395 union READLINK3res switch (nfsstat3 status) { 396 case NFS3_OK: 397 READLINK3resok resok; 398 default: 399 READLINK3resfail resfail; 400 }; 401 402 struct READ3args { 403 nfs_fh3 file; 404 offset3 offset; 405 count3 count; 406 }; 407 408 struct READ3resok { 409 post_op_attr file_attributes; 410 count3 count; 411 bool eof; 412 opaque data<>; 413 }; 414 415 struct READ3resfail { 416 post_op_attr file_attributes; 417 }; 418 419 union READ3res switch (nfsstat3 status) { 420 case NFS3_OK: 421 READ3resok resok; 422 default: 423 READ3resfail resfail; 424 }; 425 426 enum stable_how { 427 UNSTABLE = 0, 428 DATA_SYNC = 1, 429 FILE_SYNC = 2 430 }; 431 432 struct WRITE3args { 433 nfs_fh3 file; 434 offset3 offset; 435 count3 count; 436 stable_how stable; 437 opaque data<>; 438 }; 439 440 struct WRITE3resok { 441 wcc_data file_wcc; 442 count3 count; 443 stable_how committed; 444 writeverf3 verf; 445 }; 446 447 struct WRITE3resfail { 448 wcc_data file_wcc; 449 }; 450 451 union WRITE3res switch (nfsstat3 status) { 452 case NFS3_OK: 453 WRITE3resok resok; 454 default: 455 WRITE3resfail resfail; 456 }; 457 458 459 enum createmode3 { 460 UNCHECKED = 0, 461 GUARDED = 1, 462 EXCLUSIVE = 2 463 }; 464 465 union createhow3 switch (createmode3 mode) { 466 case UNCHECKED: 467 case GUARDED: 468 sattr3 obj_attributes; 469 case EXCLUSIVE: 470 createverf3 verf; 471 }; 472 473 struct CREATE3args { 474 diropargs3 where; 475 createhow3 how; 476 }; 477 478 struct CREATE3resok { 479 post_op_fh3 obj; 480 post_op_attr obj_attributes; 481 wcc_data dir_wcc; 482 }; 483 484 struct CREATE3resfail { 485 wcc_data dir_wcc; 486 }; 487 488 union CREATE3res switch (nfsstat3 status) { 489 case NFS3_OK: 490 CREATE3resok resok; 491 default: 492 CREATE3resfail resfail; 493 }; 494 495 496 struct MKDIR3args { 497 diropargs3 where; 498 sattr3 attributes; 499 }; 500 501 struct MKDIR3resok { 502 post_op_fh3 obj; 503 post_op_attr obj_attributes; 504 wcc_data dir_wcc; 505 }; 506 507 struct MKDIR3resfail { 508 wcc_data dir_wcc; 509 }; 510 511 union MKDIR3res switch (nfsstat3 status) { 512 case NFS3_OK: 513 MKDIR3resok resok; 514 default: 515 MKDIR3resfail resfail; 516 }; 517 518 519 struct symlinkdata3 { 520 sattr3 symlink_attributes; 521 nfspath3 symlink_data; 522 }; 523 524 struct SYMLINK3args { 525 diropargs3 where; 526 symlinkdata3 symlink; 527 }; 528 529 struct SYMLINK3resok { 530 post_op_fh3 obj; 531 post_op_attr obj_attributes; 532 wcc_data dir_wcc; 533 }; 534 535 struct SYMLINK3resfail { 536 wcc_data dir_wcc; 537 }; 538 539 union SYMLINK3res switch (nfsstat3 status) { 540 case NFS3_OK: 541 SYMLINK3resok resok; 542 default: 543 SYMLINK3resfail resfail; 544 }; 545 546 547 struct devicedata3 { 548 sattr3 dev_attributes; 549 specdata3 spec; 550 }; 551 552 union mknoddata3 switch (ftype3 type) { 553 case NF3CHR: 554 case NF3BLK: 555 devicedata3 device; 556 case NF3SOCK: 557 case NF3FIFO: 558 sattr3 pipe_attributes; 559 default: 560 void; 561 }; 562 563 struct MKNOD3args { 564 diropargs3 where; 565 mknoddata3 what; 566 }; 567 568 struct MKNOD3resok { 569 post_op_fh3 obj; 570 post_op_attr obj_attributes; 571 wcc_data dir_wcc; 572 }; 573 574 struct MKNOD3resfail { 575 wcc_data dir_wcc; 576 }; 577 578 union MKNOD3res switch (nfsstat3 status) { 579 case NFS3_OK: 580 MKNOD3resok resok; 581 default: 582 MKNOD3resfail resfail; 583 }; 584 585 struct REMOVE3args { 586 diropargs3 object; 587 }; 588 589 struct REMOVE3resok { 590 wcc_data dir_wcc; 591 }; 592 593 struct REMOVE3resfail { 594 wcc_data dir_wcc; 595 }; 596 597 union REMOVE3res switch (nfsstat3 status) { 598 case NFS3_OK: 599 REMOVE3resok resok; 600 default: 601 REMOVE3resfail resfail; 602 }; 603 604 605 struct RMDIR3args { 606 diropargs3 object; 607 }; 608 609 struct RMDIR3resok { 610 wcc_data dir_wcc; 611 }; 612 613 struct RMDIR3resfail { 614 wcc_data dir_wcc; 615 }; 616 617 union RMDIR3res switch (nfsstat3 status) { 618 case NFS3_OK: 619 RMDIR3resok resok; 620 default: 621 RMDIR3resfail resfail; 622 }; 623 624 struct RENAME3args { 625 diropargs3 from; 626 diropargs3 to; 627 }; 628 629 struct RENAME3resok { 630 wcc_data fromdir_wcc; 631 wcc_data todir_wcc; 632 }; 633 634 struct RENAME3resfail { 635 wcc_data fromdir_wcc; 636 wcc_data todir_wcc; 637 }; 638 639 union RENAME3res switch (nfsstat3 status) { 640 case NFS3_OK: 641 RENAME3resok resok; 642 default: 643 RENAME3resfail resfail; 644 }; 645 646 struct LINK3args { 647 nfs_fh3 file; 648 diropargs3 link; 649 }; 650 651 struct LINK3resok { 652 post_op_attr file_attributes; 653 wcc_data linkdir_wcc; 654 }; 655 656 struct LINK3resfail { 657 post_op_attr file_attributes; 658 wcc_data linkdir_wcc; 659 }; 660 661 union LINK3res switch (nfsstat3 status) { 662 case NFS3_OK: 663 664 LINK3resok resok; 665 default: 666 LINK3resfail resfail; 667 }; 668 669 struct READDIR3args { 670 nfs_fh3 dir; 671 cookie3 cookie; 672 cookieverf3 cookieverf; 673 count3 count; 674 }; 675 676 struct entry3 { 677 fileid3 fileid; 678 filename3 name; 679 cookie3 cookie; 680 entry3 *nextentry; 681 }; 682 683 struct dirlist3 { 684 entry3 *entries; 685 bool eof; 686 }; 687 688 struct READDIR3resok { 689 post_op_attr dir_attributes; 690 cookieverf3 cookieverf; 691 dirlist3 reply; 692 }; 693 694 struct READDIR3resfail { 695 post_op_attr dir_attributes; 696 }; 697 698 union READDIR3res switch (nfsstat3 status) { 699 case NFS3_OK: 700 READDIR3resok resok; 701 default: 702 READDIR3resfail resfail; 703 }; 704 705 struct READDIRPLUS3args { 706 nfs_fh3 dir; 707 cookie3 cookie; 708 cookieverf3 cookieverf; 709 count3 dircount; 710 count3 maxcount; 711 }; 712 713 struct entryplus3 { 714 fileid3 fileid; 715 filename3 name; 716 cookie3 cookie; 717 post_op_attr name_attributes; 718 post_op_fh3 name_handle; 719 entryplus3 *nextentry; 720 }; 721 722 struct dirlistplus3 { 723 entryplus3 *entries; 724 bool eof; 725 }; 726 727 struct READDIRPLUS3resok { 728 post_op_attr dir_attributes; 729 cookieverf3 cookieverf; 730 dirlistplus3 reply; 731 }; 732 733 struct READDIRPLUS3resfail { 734 post_op_attr dir_attributes; 735 }; 736 737 union READDIRPLUS3res switch (nfsstat3 status) { 738 case NFS3_OK: 739 READDIRPLUS3resok resok; 740 default: 741 READDIRPLUS3resfail resfail; 742 }; 743 744 struct FSSTAT3args { 745 nfs_fh3 fsroot; 746 }; 747 748 struct FSSTAT3resok { 749 post_op_attr obj_attributes; 750 size3 tbytes; 751 size3 fbytes; 752 size3 abytes; 753 size3 tfiles; 754 size3 ffiles; 755 size3 afiles; 756 uint32 invarsec; 757 }; 758 759 struct FSSTAT3resfail { 760 post_op_attr obj_attributes; 761 }; 762 763 union FSSTAT3res switch (nfsstat3 status) { 764 case NFS3_OK: 765 FSSTAT3resok resok; 766 default: 767 FSSTAT3resfail resfail; 768 }; 769 770 const FSF3_LINK = 0x0001; 771 const FSF3_SYMLINK = 0x0002; 772 const FSF3_HOMOGENEOUS = 0x0008; 773 const FSF3_CANSETTIME = 0x0010; 774 775 struct FSINFO3args { 776 nfs_fh3 fsroot; 777 }; 778 779 struct FSINFO3resok { 780 post_op_attr obj_attributes; 781 uint32 rtmax; 782 uint32 rtpref; 783 uint32 rtmult; 784 uint32 wtmax; 785 uint32 wtpref; 786 uint32 wtmult; 787 uint32 dtpref; 788 789 size3 maxfilesize; 790 nfstime3 time_delta; 791 uint32 properties; 792 }; 793 794 struct FSINFO3resfail { 795 post_op_attr obj_attributes; 796 }; 797 798 union FSINFO3res switch (nfsstat3 status) { 799 case NFS3_OK: 800 FSINFO3resok resok; 801 default: 802 FSINFO3resfail resfail; 803 }; 804 805 struct PATHCONF3args { 806 nfs_fh3 object; 807 }; 808 809 struct PATHCONF3resok { 810 post_op_attr obj_attributes; 811 uint32 linkmax; 812 uint32 name_max; 813 bool no_trunc; 814 bool chown_restricted; 815 bool case_insensitive; 816 bool case_preserving; 817 }; 818 819 struct PATHCONF3resfail { 820 post_op_attr obj_attributes; 821 }; 822 823 union PATHCONF3res switch (nfsstat3 status) { 824 case NFS3_OK: 825 PATHCONF3resok resok; 826 default: 827 PATHCONF3resfail resfail; 828 }; 829 830 struct COMMIT3args { 831 nfs_fh3 file; 832 offset3 offset; 833 count3 count; 834 }; 835 836 struct COMMIT3resok { 837 wcc_data file_wcc; 838 writeverf3 verf; 839 }; 840 841 struct COMMIT3resfail { 842 wcc_data file_wcc; 843 }; 844 845 union COMMIT3res switch (nfsstat3 status) { 846 case NFS3_OK: 847 COMMIT3resok resok; 848 default: 849 COMMIT3resfail resfail; 850 }; 851 852 853 const MNTPATHLEN3 = 1024; /* Maximum bytes in a path name */ 854 const MNTNAMLEN3 = 255; /* Maximum bytes in a name */ 855 const FHSIZE3 = 64; /* Maximum bytes in a V3 file handle */ 856 857 typedef opaque fhandle3<FHSIZE3>; 858 typedef string dirpath3<MNTPATHLEN3>; 859 typedef string name3<MNTNAMLEN3>; 860 861 enum mountstat3 { 862 MNT3_OK = 0, /* no error */ 863 MNT3ERR_PERM = 1, /* Not owner */ 864 MNT3ERR_NOENT = 2, /* No such file or directory */ 865 MNT3ERR_IO = 5, /* I/O error */ 866 MNT3ERR_ACCES = 13, /* Permission denied */ 867 MNT3ERR_NOTDIR = 20, /* Not a directory */ 868 MNT3ERR_INVAL = 22, /* Invalid argument */ 869 MNT3ERR_NAMETOOLONG = 63, /* Filename too long */ 870 MNT3ERR_NOTSUPP = 10004, /* Operation not supported */ 871 MNT3ERR_SERVERFAULT = 10006 /* A failure on the server */ 872 }; 873 874 875 program MOUNT_PROGRAM { 876 version MOUNT_V3 { 877 void MOUNTPROC3_NULL(void) = 0; 878 mountres3 MOUNTPROC3_MNT(dirpath3) = 1; 879 mountlist3 MOUNTPROC3_DUMP(void) = 2; 880 void MOUNTPROC3_UMNT(dirpath3) = 3; 881 void MOUNTPROC3_UMNTALL(void) = 4; 882 exports3 MOUNTPROC3_EXPORT(void) = 5; 883 } = 3; 884 } = 100005; 885 886 struct mountres3_ok { 887 fhandle3 fhandle; 888 int auth_flavors<>; 889 }; 890 891 union mountres3 switch (mountstat3 fhs_status) { 892 case MNT3_OK: 893 mountres3_ok mountinfo; 894 default: 895 void; 896 }; 897 898 typedef struct mountbody3 *mountlist3; 899 900 struct mountbody3 { 901 name3 ml_hostname; 902 dirpath3 ml_directory; 903 mountlist3 ml_next; 904 }; 905 906 907 typedef struct groupnode3 *groups3; 908 909 struct groupnode3 { 910 name3 gr_name; 911 groups3 gr_next; 912 }; 913 914 typedef struct exportnode3 *exports3; 915 916 struct exportnode3 { 917 dirpath3 ex_dir; 918 groups3 ex_groups; 919 exports3 ex_next; 920 }; 921