1 /*********************************************************************** 2 * * 3 * This software is part of the ast package * 4 * Copyright (c) 1985-2010 AT&T Intellectual Property * 5 * and is licensed under the * 6 * Common Public License, Version 1.0 * 7 * by AT&T Intellectual Property * 8 * * 9 * A copy of the License is available at * 10 * http://www.opensource.org/licenses/cpl1.0.txt * 11 * (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) * 12 * * 13 * Information and Software Systems Research * 14 * AT&T Research * 15 * Florham Park NJ * 16 * * 17 * Glenn Fowler <gsf@research.att.com> * 18 * David Korn <dgk@research.att.com> * 19 * Phong Vo <kpv@research.att.com> * 20 * * 21 ***********************************************************************/ 22 #pragma prototyped 23 /* 24 * Glenn Fowler 25 * AT&T Research 26 * 27 * mounted filesystem scan support 28 * where are the standards when you really need them 29 */ 30 31 #include <ast.h> 32 #include <mnt.h> 33 #include <ls.h> 34 35 #if _lib_mntopen && _lib_mntread && _lib_mntclose 36 37 NoN(mnt) 38 39 #else 40 41 /* 42 * the original interface just had mode 43 */ 44 45 #define FIXARGS(p,m,s) do { \ 46 if ((p)&&*(p)!='/') { \ 47 mode = p; \ 48 path = 0; \ 49 } \ 50 if (!path) \ 51 path = s; \ 52 } while (0) 53 typedef struct 54 { 55 Mnt_t mnt; 56 char buf[128]; 57 #if __CYGWIN__ 58 char typ[128]; 59 char opt[128]; 60 #endif 61 } Header_t; 62 63 #if __CYGWIN__ 64 #include <ast_windows.h> 65 #endif 66 67 static void 68 set(register Header_t* hp, const char* fs, const char* dir, const char* type, const char* options) 69 { 70 const char* x; 71 72 hp->mnt.flags = 0; 73 if (x = (const char*)strchr(fs, ':')) 74 { 75 if (*++x && *x != '\\') 76 { 77 hp->mnt.flags |= MNT_REMOTE; 78 if (*x == '(') 79 { 80 fs = x; 81 type = "auto"; 82 } 83 } 84 } 85 else if (x = (const char*)strchr(fs, '@')) 86 { 87 hp->mnt.flags |= MNT_REMOTE; 88 sfsprintf(hp->buf, sizeof(hp->buf) - 1, "%s:%*.*s", x + 1, x - fs, x - fs, fs); 89 fs = (const char*)hp->buf; 90 } 91 else if (strmatch(type, "[aAnN][fF][sS]*")) 92 hp->mnt.flags |= MNT_REMOTE; 93 if (streq(fs, "none")) 94 fs = dir; 95 hp->mnt.fs = (char*)fs; 96 hp->mnt.dir = (char*)dir; 97 hp->mnt.type = (char*)type; 98 hp->mnt.options = (char*)options; 99 #if __CYGWIN__ 100 if (streq(type, "system") || streq(type, "user")) 101 { 102 char* s; 103 int mode; 104 DWORD vser; 105 DWORD flags; 106 DWORD len; 107 char drive[4]; 108 109 mode = SetErrorMode(SEM_FAILCRITICALERRORS); 110 drive[0] = fs[0]; 111 drive[1] = ':'; 112 drive[2] = '\\'; 113 drive[3] = 0; 114 if (GetVolumeInformation(drive, 0, 0, &vser, &len, &flags, hp->typ, sizeof(hp->typ) - 1)) 115 hp->mnt.type = hp->typ; 116 else 117 flags = 0; 118 SetErrorMode(mode); 119 s = strcopy(hp->mnt.options = hp->opt, type); 120 s = strcopy(s, ",ignorecase"); 121 if (options) 122 { 123 *s++ = ','; 124 strcpy(s, options); 125 } 126 } 127 #endif 128 } 129 130 #undef MNT_REMOTE 131 132 #if _lib_getmntinfo && _sys_mount 133 134 /* 135 * 4.4 bsd 136 * 137 * what a crappy interface 138 * data returned in static buffer -- ok 139 * big chunk of allocated memory that cannot be freed -- come on 140 * *and* netbsd changed the interface somewhere along the line 141 * private interface? my bad -- public interface? par for the bsd course 142 */ 143 144 #include <sys/param.h> /* expect some macro redefinitions here */ 145 #include <sys/mount.h> 146 147 #if _lib_getmntinfo_statvfs 148 #define statfs statvfs 149 #define f_flags f_flag 150 #endif 151 152 typedef struct 153 { 154 Header_t hdr; 155 struct statfs* next; 156 struct statfs* last; 157 char opt[256]; 158 } Handle_t; 159 160 #ifdef MFSNAMELEN 161 #define TYPE(f) ((f)->f_fstypename) 162 #else 163 #ifdef INITMOUNTNAMES 164 #define TYPE(f) ((char*)type[(f)->f_type]) 165 static const char* type[] = INITMOUNTNAMES; 166 #else 167 #if _sys_fs_types 168 #define TYPE(f) ((char*)mnt_names[(f)->f_type]) 169 #include <sys/fs_types.h> 170 #else 171 #define TYPE(f) (strchr((f)->f_mntfromname,':')?"nfs":"ufs") 172 #endif 173 #endif 174 #endif 175 176 static struct Mnt_options_t 177 { 178 unsigned long flag; 179 const char* name; 180 } 181 options[] = 182 { 183 #ifdef MNT_RDONLY 184 MNT_RDONLY, "rdonly", 185 #endif 186 #ifdef MNT_SYNCHRONOUS 187 MNT_SYNCHRONOUS,"synchronous", 188 #endif 189 #ifdef MNT_NOEXEC 190 MNT_NOEXEC, "noexec", 191 #endif 192 #ifdef MNT_NOSUID 193 MNT_NOSUID, "nosuid", 194 #endif 195 #ifdef MNT_NODEV 196 MNT_NODEV, "nodev", 197 #endif 198 #ifdef MNT_UNION 199 MNT_UNION, "union", 200 #endif 201 #ifdef MNT_ASYNC 202 MNT_ASYNC, "async", 203 #endif 204 #ifdef MNT_NOCOREDUMP 205 MNT_NOCOREDUMP, "nocoredump", 206 #endif 207 #ifdef MNT_NOATIME 208 MNT_NOATIME, "noatime", 209 #endif 210 #ifdef MNT_SYMPERM 211 MNT_SYMPERM, "symperm", 212 #endif 213 #ifdef MNT_NODEVMTIME 214 MNT_NODEVMTIME, "nodevmtime", 215 #endif 216 #ifdef MNT_SOFTDEP 217 MNT_SOFTDEP, "softdep", 218 #endif 219 #ifdef MNT_EXRDONLY 220 MNT_EXRDONLY, "exrdonly", 221 #endif 222 #ifdef MNT_EXPORTED 223 MNT_EXPORTED, "exported", 224 #endif 225 #ifdef MNT_DEFEXPORTED 226 MNT_DEFEXPORTED,"defexported", 227 #endif 228 #ifdef MNT_EXPORTANON 229 MNT_EXPORTANON, "exportanon", 230 #endif 231 #ifdef MNT_EXKERB 232 MNT_EXKERB, "exkerb", 233 #endif 234 #ifdef MNT_EXNORESPORT 235 MNT_EXNORESPORT,"exnoresport", 236 #endif 237 #ifdef MNT_EXPUBLIC 238 MNT_EXPUBLIC, "expublic", 239 #endif 240 #ifdef MNT_LOCAL 241 MNT_LOCAL, "local", 242 #endif 243 #ifdef MNT_QUOTA 244 MNT_QUOTA, "quota", 245 #endif 246 #ifdef MNT_ROOTFS 247 MNT_ROOTFS, "rootfs", 248 #endif 249 0, "unknown", 250 }; 251 252 void* 253 mntopen(const char* path, const char* mode) 254 { 255 register Handle_t* mp; 256 register int n; 257 258 FIXARGS(path, mode, 0); 259 if (!(mp = newof(0, Handle_t, 1, 0))) 260 return 0; 261 if ((n = getmntinfo(&mp->next, 0)) <= 0) 262 { 263 free(mp); 264 return 0; 265 } 266 mp->last = mp->next + n; 267 return (void*)mp; 268 } 269 270 Mnt_t* 271 mntread(void* handle) 272 { 273 register Handle_t* mp = (Handle_t*)handle; 274 register int i; 275 register int n; 276 register unsigned long flags; 277 278 if (mp->next < mp->last) 279 { 280 flags = mp->next->f_flags; 281 n = 0; 282 for (i = 0; i < elementsof(options); i++) 283 if (flags & options[i].flag) 284 n += sfsprintf(mp->opt + n, sizeof(mp->opt) - n - 1, ",%s", options[i].name); 285 set(&mp->hdr, mp->next->f_mntfromname, mp->next->f_mntonname, TYPE(mp->next), n ? (mp->opt + 1) : (char*)0); 286 mp->next++; 287 return &mp->hdr.mnt; 288 } 289 return 0; 290 } 291 292 int 293 mntclose(void* handle) 294 { 295 register Handle_t* mp = (Handle_t*)handle; 296 297 if (!mp) 298 return -1; 299 free(mp); 300 return 0; 301 } 302 303 #else 304 305 #if _lib_mntctl && _sys_vmount 306 307 /* 308 * aix 309 */ 310 311 #include <sys/vmount.h> 312 313 #define SIZE (16 * 1024) 314 315 static const char* type[] = 316 { 317 "aix", "aix#1", "nfs", "jfs", "aix#4", "cdrom" 318 }; 319 320 typedef struct 321 { 322 Header_t hdr; 323 long count; 324 struct vmount* next; 325 char remote[128]; 326 char type[16]; 327 struct vmount info[1]; 328 } Handle_t; 329 330 void* 331 mntopen(const char* path, const char* mode) 332 { 333 register Handle_t* mp; 334 335 FIXARGS(path, mode, 0); 336 if (!(mp = newof(0, Handle_t, 1, SIZE))) 337 return 0; 338 if ((mp->count = mntctl(MCTL_QUERY, sizeof(Handle_t) + SIZE, &mp->info)) <= 0) 339 { 340 free(mp); 341 return 0; 342 } 343 mp->next = mp->info; 344 return (void*)mp; 345 } 346 347 Mnt_t* 348 mntread(void* handle) 349 { 350 register Handle_t* mp = (Handle_t*)handle; 351 register char* s; 352 register char* t; 353 register char* o; 354 355 if (mp->count > 0) 356 { 357 if (vmt2datasize(mp->next, VMT_HOST) && (s = vmt2dataptr(mp->next, VMT_HOST)) && !streq(s, "-")) 358 { 359 sfsprintf(mp->remote, sizeof(mp->remote) - 1, "%s:%s", s, vmt2dataptr(mp->next, VMT_OBJECT)); 360 s = mp->remote; 361 } 362 else 363 s = vmt2dataptr(mp->next, VMT_OBJECT); 364 if (vmt2datasize(mp->next, VMT_ARGS)) 365 o = vmt2dataptr(mp->next, VMT_ARGS); 366 else 367 o = NiL; 368 switch (mp->next->vmt_gfstype) 369 { 370 #ifdef MNT_AIX 371 case MNT_AIX: 372 t = "aix"; 373 break; 374 #endif 375 #ifdef MNT_NFS 376 case MNT_NFS: 377 t = "nfs"; 378 break; 379 #endif 380 #ifdef MNT_JFS 381 case MNT_JFS: 382 t = "jfs"; 383 break; 384 #endif 385 #ifdef MNT_CDROM 386 case MNT_CDROM: 387 t = "cdrom"; 388 break; 389 #endif 390 #ifdef MNT_SFS 391 case MNT_SFS: 392 t = "sfs"; 393 break; 394 #endif 395 #ifdef MNT_CACHEFS 396 case MNT_CACHEFS: 397 t = "cachefs"; 398 break; 399 #endif 400 #ifdef MNT_NFS3 401 case MNT_NFS3: 402 t = "nfs3"; 403 break; 404 #endif 405 #ifdef MNT_AUTOFS 406 case MNT_AUTOFS: 407 t = "autofs"; 408 break; 409 #endif 410 default: 411 sfsprintf(t = mp->type, sizeof(mp->type), "aix%+d", mp->next->vmt_gfstype); 412 break; 413 } 414 set(&mp->hdr, s, vmt2dataptr(mp->next, VMT_STUB), t, o); 415 if (--mp->count > 0) 416 mp->next = (struct vmount*)((char*)mp->next + mp->next->vmt_length); 417 return &mp->hdr.mnt; 418 } 419 return 0; 420 } 421 422 int 423 mntclose(void* handle) 424 { 425 register Handle_t* mp = (Handle_t*)handle; 426 427 if (!mp) 428 return -1; 429 free(mp); 430 return 0; 431 } 432 433 #else 434 435 #if !_lib_setmntent 436 #undef _lib_getmntent 437 #if !_SCO_COFF && !_SCO_ELF && !_UTS 438 #undef _hdr_mnttab 439 #endif 440 #endif 441 442 #if _lib_getmntent && ( _hdr_mntent || _sys_mntent && !_sys_mnttab ) 443 444 #if defined(__STDPP__directive) && defined(__STDPP__hide) 445 __STDPP__directive pragma pp:hide endmntent getmntent 446 #else 447 #define endmntent ______endmntent 448 #define getmntent ______getmntent 449 #endif 450 451 #include <stdio.h> 452 #if _hdr_mntent 453 #include <mntent.h> 454 #else 455 #include <sys/mntent.h> 456 #endif 457 458 #if defined(__STDPP__directive) && defined(__STDPP__hide) 459 __STDPP__directive pragma pp:nohide endmntent getmntent 460 #else 461 #undef endmntent 462 #undef getmntent 463 #endif 464 465 extern int endmntent(FILE*); 466 extern struct mntent* getmntent(FILE*); 467 468 #else 469 470 #undef _lib_getmntent 471 472 #if _hdr_mnttab 473 #include <mnttab.h> 474 #else 475 #if _sys_mnttab 476 #include <sys/mnttab.h> 477 #endif 478 #endif 479 480 #endif 481 482 #ifndef MOUNTED 483 #ifdef MNT_MNTTAB 484 #define MOUNTED MNT_MNTTAB 485 #else 486 #if _hdr_mnttab || _sys_mnttab 487 #define MOUNTED "/etc/mnttab" 488 #else 489 #define MOUNTED "/etc/mtab" 490 #endif 491 #endif 492 #endif 493 494 #ifdef __Lynx__ 495 #undef MOUNTED 496 #define MOUNTED "/etc/fstab" 497 #define SEP ':' 498 #endif 499 500 #if _lib_getmntent 501 502 typedef struct 503 #if _mem_mnt_opts_mntent 504 #define OPTIONS(p) ((p)->mnt_opts) 505 #else 506 #define OPTIONS(p) NiL 507 #endif 508 509 { 510 Header_t hdr; 511 FILE* fp; 512 } Handle_t; 513 514 void* 515 mntopen(const char* path, const char* mode) 516 { 517 register Handle_t* mp; 518 519 FIXARGS(path, mode, MOUNTED); 520 if (!(mp = newof(0, Handle_t, 1, 0))) 521 return 0; 522 if (!(mp->fp = setmntent(path, mode))) 523 { 524 free(mp); 525 return 0; 526 } 527 return (void*)mp; 528 } 529 530 Mnt_t* 531 mntread(void* handle) 532 { 533 register Handle_t* mp = (Handle_t*)handle; 534 register struct mntent* mnt; 535 536 if (mnt = getmntent(mp->fp)) 537 { 538 set(&mp->hdr, mnt->mnt_fsname, mnt->mnt_dir, mnt->mnt_type, OPTIONS(mnt)); 539 return &mp->hdr.mnt; 540 } 541 return 0; 542 } 543 544 int 545 mntclose(void* handle) 546 { 547 register Handle_t* mp = (Handle_t*)handle; 548 549 if (!mp) 550 return -1; 551 endmntent(mp->fp); 552 free(mp); 553 return 0; 554 } 555 556 #else 557 558 #if _sys_mntent && _lib_w_getmntent 559 560 #include <sys/mntent.h> 561 562 #define mntent w_mntent 563 564 #define mnt_dir mnt_mountpoint 565 #define mnt_type mnt_fstname 566 567 #define MNTBUFSIZE (sizeof(struct w_mnth)+16*sizeof(struct w_mntent)) 568 569 #if _mem_mnt_opts_w_mntent 570 #define OPTIONS(p) ((p)->mnt_opts) 571 #else 572 #define OPTIONS(p) NiL 573 #endif 574 575 #else 576 577 #undef _lib_w_getmntent 578 579 #define MNTBUFSIZE sizeof(struct mntent) 580 581 #if !_mem_mt_dev_mnttab || !_mem_mt_filsys_mnttab 582 #undef _hdr_mnttab 583 #endif 584 585 #if _hdr_mnttab 586 587 #define mntent mnttab 588 589 #define mnt_fsname mt_dev 590 #define mnt_dir mt_filsys 591 #if _mem_mt_fstyp_mnttab 592 #define mnt_type mt_fstyp 593 #endif 594 595 #if _mem_mnt_opts_mnttab 596 #define OPTIONS(p) ((p)->mnt_opts) 597 #else 598 #define OPTIONS(p) NiL 599 #endif 600 601 #else 602 603 struct mntent 604 { 605 char mnt_fsname[256]; 606 char mnt_dir[256]; 607 char mnt_type[32]; 608 char mnt_opts[64]; 609 }; 610 611 #define OPTIONS(p) ((p)->mnt_opts) 612 613 #endif 614 615 #endif 616 617 typedef struct 618 { 619 Header_t hdr; 620 Sfio_t* fp; 621 struct mntent* mnt; 622 #if _lib_w_getmntent 623 int count; 624 #endif 625 char buf[MNTBUFSIZE]; 626 } Handle_t; 627 628 void* 629 mntopen(const char* path, const char* mode) 630 { 631 register Handle_t* mp; 632 633 FIXARGS(path, mode, MOUNTED); 634 if (!(mp = newof(0, Handle_t, 1, 0))) 635 return 0; 636 #if _lib_w_getmntent 637 if ((mp->count = w_getmntent(mp->buf, sizeof(mp->buf))) > 0) 638 mp->mnt = (struct mntent*)(((struct w_mnth*)mp->buf) + 1); 639 else 640 #else 641 mp->mnt = (struct mntent*)mp->buf; 642 if (!(mp->fp = sfopen(NiL, path, mode))) 643 #endif 644 { 645 free(mp); 646 return 0; 647 } 648 return (void*)mp; 649 } 650 651 Mnt_t* 652 mntread(void* handle) 653 { 654 register Handle_t* mp = (Handle_t*)handle; 655 656 #if _lib_w_getmntent 657 658 if (mp->count-- <= 0) 659 { 660 if ((mp->count = w_getmntent(mp->buf, sizeof(mp->buf))) <= 0) 661 return 0; 662 mp->count--; 663 mp->mnt = (struct mntent*)(((struct w_mnth*)mp->buf) + 1); 664 } 665 set(&mp->hdr, mp->mnt->mnt_fsname, mp->mnt->mnt_dir, mp->mnt->mnt_type, OPTIONS(mp->mnt)); 666 mp->mnt++; 667 return &mp->hdr.mnt; 668 669 #else 670 671 #if _hdr_mnttab 672 673 while (sfread(mp->fp, &mp->buf, sizeof(mp->buf)) == sizeof(mp->buf)) 674 if (*mp->mnt->mnt_fsname && *mp->mnt->mnt_dir) 675 { 676 #ifndef mnt_type 677 struct stat st; 678 679 static char typ[32]; 680 681 set(&mp->hdr, mp->mnt->mnt_fsname, mp->mnt->mnt_dir, stat(mp->mnt->mnt_dir, &st) ? FS_default : strncpy(typ, fmtfs(&st), sizeof(typ) - 1), OPTIONS(mp->mnt)); 682 #else 683 set(&mp->hdr, mp->mnt->mnt_fsname, mp->mnt->mnt_dir, mp->mnt->mnt_type, OPTIONS(mp->mnt)); 684 #endif 685 return &mp->hdr.mnt; 686 } 687 return 0; 688 689 #else 690 691 register int c; 692 register char* s; 693 register char* m; 694 register char* b; 695 register int q; 696 register int x; 697 698 again: 699 q = 0; 700 x = 0; 701 b = s = mp->mnt->mnt_fsname; 702 m = s + sizeof(mp->mnt->mnt_fsname) - 1; 703 for (;;) switch (c = sfgetc(mp->fp)) 704 { 705 case EOF: 706 return 0; 707 case '"': 708 case '\'': 709 if (q == c) 710 q = 0; 711 else if (!q) 712 q = c; 713 break; 714 #ifdef SEP 715 case SEP: 716 #else 717 case ' ': 718 case '\t': 719 #endif 720 if (s != b && !q) switch (++x) 721 { 722 case 1: 723 *s = 0; 724 b = s = mp->mnt->mnt_dir; 725 m = s + sizeof(mp->mnt->mnt_dir) - 1; 726 break; 727 case 2: 728 *s = 0; 729 b = s = mp->mnt->mnt_type; 730 m = s + sizeof(mp->mnt->mnt_type) - 1; 731 break; 732 case 3: 733 *s = 0; 734 b = s = mp->mnt->mnt_opts; 735 m = s + sizeof(mp->mnt->mnt_opts) - 1; 736 break; 737 case 4: 738 *s = 0; 739 b = s = m = 0; 740 break; 741 } 742 break; 743 case '\n': 744 if (x >= 3) 745 { 746 set(&mp->hdr, mp->mnt->mnt_fsname, mp->mnt->mnt_dir, mp->mnt->mnt_type, OPTIONS(mp->mnt)); 747 return &mp->hdr.mnt; 748 } 749 goto again; 750 default: 751 if (s < m) 752 *s++ = c; 753 break; 754 } 755 756 #endif 757 758 #endif 759 760 } 761 762 int 763 mntclose(void* handle) 764 { 765 register Handle_t* mp = (Handle_t*)handle; 766 767 if (!mp) 768 return -1; 769 sfclose(mp->fp); 770 free(mp); 771 return 0; 772 } 773 774 #endif 775 776 #endif 777 778 #endif 779 780 /* 781 * currently no write 782 */ 783 784 int 785 mntwrite(void* handle, const Mnt_t* mnt) 786 { 787 NoP(handle); 788 NoP(mnt); 789 return -1; 790 } 791 792 #endif 793