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