dmake: do not set MAKEFLAGS=k
[unleashed/tickless.git] / usr / src / lib / libast / common / port / mnt.c
blob080abed431ea85cf7524dcbefea57d8caef37ccc
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
24 * Glenn Fowler
25 * AT&T Research
27 * mounted filesystem scan support
28 * where are the standards when you really need them
31 #include <ast.h>
32 #include <mnt.h>
33 #include <ls.h>
35 #if _lib_mntopen && _lib_mntread && _lib_mntclose
37 NoN(mnt)
39 #else
42 * the original interface just had mode
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
55 Mnt_t mnt;
56 char buf[128];
57 #if __CYGWIN__
58 char typ[128];
59 char opt[128];
60 #endif
61 } Header_t;
63 #if __CYGWIN__
64 #include <ast_windows.h>
65 #endif
67 static void
68 set(register Header_t* hp, const char* fs, const char* dir, const char* type, const char* options)
70 const char* x;
72 hp->mnt.flags = 0;
73 if (x = (const char*)strchr(fs, ':'))
75 if (*++x && *x != '\\')
77 hp->mnt.flags |= MNT_REMOTE;
78 if (*x == '(')
80 fs = x;
81 type = "auto";
85 else if (x = (const char*)strchr(fs, '@'))
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;
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"))
102 char* s;
103 int mode;
104 DWORD vser;
105 DWORD flags;
106 DWORD len;
107 char drive[4];
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)
123 *s++ = ',';
124 strcpy(s, options);
127 #endif
130 #undef MNT_REMOTE
132 #if _lib_getmntinfo && _sys_mount
135 * 4.4 bsd
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
144 #include <sys/param.h> /* expect some macro redefinitions here */
145 #include <sys/mount.h>
147 #if _lib_getmntinfo_statvfs
148 #define statfs statvfs
149 #define f_flags f_flag
150 #endif
152 typedef struct
154 Header_t hdr;
155 struct statfs* next;
156 struct statfs* last;
157 char opt[256];
158 } Handle_t;
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
176 static struct Mnt_options_t
178 unsigned long flag;
179 const char* name;
181 options[] =
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",
252 void*
253 mntopen(const char* path, const char* mode)
255 register Handle_t* mp;
256 register int n;
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)
263 free(mp);
264 return 0;
266 mp->last = mp->next + n;
267 return (void*)mp;
270 Mnt_t*
271 mntread(void* handle)
273 register Handle_t* mp = (Handle_t*)handle;
274 register int i;
275 register int n;
276 register unsigned long flags;
278 if (mp->next < mp->last)
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;
289 return 0;
293 mntclose(void* handle)
295 register Handle_t* mp = (Handle_t*)handle;
297 if (!mp)
298 return -1;
299 free(mp);
300 return 0;
303 #else
305 #if _lib_mntctl && _sys_vmount
308 * aix
311 #include <sys/vmount.h>
313 #define SIZE (16 * 1024)
315 static const char* type[] =
317 "aix", "aix#1", "nfs", "jfs", "aix#4", "cdrom"
320 typedef struct
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;
330 void*
331 mntopen(const char* path, const char* mode)
333 register Handle_t* mp;
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)
340 free(mp);
341 return 0;
343 mp->next = mp->info;
344 return (void*)mp;
347 Mnt_t*
348 mntread(void* handle)
350 register Handle_t* mp = (Handle_t*)handle;
351 register char* s;
352 register char* t;
353 register char* o;
355 if (mp->count > 0)
357 if (vmt2datasize(mp->next, VMT_HOST) && (s = vmt2dataptr(mp->next, VMT_HOST)) && !streq(s, "-"))
359 sfsprintf(mp->remote, sizeof(mp->remote) - 1, "%s:%s", s, vmt2dataptr(mp->next, VMT_OBJECT));
360 s = mp->remote;
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)
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;
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;
419 return 0;
423 mntclose(void* handle)
425 register Handle_t* mp = (Handle_t*)handle;
427 if (!mp)
428 return -1;
429 free(mp);
430 return 0;
433 #else
435 #if !_lib_setmntent
436 #undef _lib_getmntent
437 #if !_SCO_COFF && !_SCO_ELF && !_UTS
438 #undef _hdr_mnttab
439 #endif
440 #endif
442 #if _lib_getmntent && ( _hdr_mntent || _sys_mntent && !_sys_mnttab )
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
451 #include <stdio.h>
452 #if _hdr_mntent
453 #include <mntent.h>
454 #else
455 #include <sys/mntent.h>
456 #endif
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
465 extern int endmntent(FILE*);
466 extern struct mntent* getmntent(FILE*);
468 #else
470 #undef _lib_getmntent
472 #if _hdr_mnttab
473 #include <mnttab.h>
474 #else
475 #if _sys_mnttab
476 #include <sys/mnttab.h>
477 #endif
478 #endif
480 #endif
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
494 #ifdef __Lynx__
495 #undef MOUNTED
496 #define MOUNTED "/etc/fstab"
497 #define SEP ':'
498 #endif
500 #if _lib_getmntent
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
510 Header_t hdr;
511 FILE* fp;
512 } Handle_t;
514 void*
515 mntopen(const char* path, const char* mode)
517 register Handle_t* mp;
519 FIXARGS(path, mode, MOUNTED);
520 if (!(mp = newof(0, Handle_t, 1, 0)))
521 return 0;
522 if (!(mp->fp = setmntent(path, mode)))
524 free(mp);
525 return 0;
527 return (void*)mp;
530 Mnt_t*
531 mntread(void* handle)
533 register Handle_t* mp = (Handle_t*)handle;
534 register struct mntent* mnt;
536 if (mnt = getmntent(mp->fp))
538 set(&mp->hdr, mnt->mnt_fsname, mnt->mnt_dir, mnt->mnt_type, OPTIONS(mnt));
539 return &mp->hdr.mnt;
541 return 0;
545 mntclose(void* handle)
547 register Handle_t* mp = (Handle_t*)handle;
549 if (!mp)
550 return -1;
551 endmntent(mp->fp);
552 free(mp);
553 return 0;
556 #else
558 #if _sys_mntent && _lib_w_getmntent
560 #include <sys/mntent.h>
562 #define mntent w_mntent
564 #define mnt_dir mnt_mountpoint
565 #define mnt_type mnt_fstname
567 #define MNTBUFSIZE (sizeof(struct w_mnth)+16*sizeof(struct w_mntent))
569 #if _mem_mnt_opts_w_mntent
570 #define OPTIONS(p) ((p)->mnt_opts)
571 #else
572 #define OPTIONS(p) NiL
573 #endif
575 #else
577 #undef _lib_w_getmntent
579 #define MNTBUFSIZE sizeof(struct mntent)
581 #if !_mem_mt_dev_mnttab || !_mem_mt_filsys_mnttab
582 #undef _hdr_mnttab
583 #endif
585 #if _hdr_mnttab
587 #define mntent mnttab
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
595 #if _mem_mnt_opts_mnttab
596 #define OPTIONS(p) ((p)->mnt_opts)
597 #else
598 #define OPTIONS(p) NiL
599 #endif
601 #else
603 struct mntent
605 char mnt_fsname[256];
606 char mnt_dir[256];
607 char mnt_type[32];
608 char mnt_opts[64];
611 #define OPTIONS(p) ((p)->mnt_opts)
613 #endif
615 #endif
617 typedef struct
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;
628 void*
629 mntopen(const char* path, const char* mode)
631 register Handle_t* mp;
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
645 free(mp);
646 return 0;
648 return (void*)mp;
651 Mnt_t*
652 mntread(void* handle)
654 register Handle_t* mp = (Handle_t*)handle;
656 #if _lib_w_getmntent
658 if (mp->count-- <= 0)
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);
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;
669 #else
671 #if _hdr_mnttab
673 while (sfread(mp->fp, &mp->buf, sizeof(mp->buf)) == sizeof(mp->buf))
674 if (*mp->mnt->mnt_fsname && *mp->mnt->mnt_dir)
676 #ifndef mnt_type
677 struct stat st;
679 static char typ[32];
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;
687 return 0;
689 #else
691 register int c;
692 register char* s;
693 register char* m;
694 register char* b;
695 register int q;
696 register int x;
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))
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)
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;
742 break;
743 case '\n':
744 if (x >= 3)
746 set(&mp->hdr, mp->mnt->mnt_fsname, mp->mnt->mnt_dir, mp->mnt->mnt_type, OPTIONS(mp->mnt));
747 return &mp->hdr.mnt;
749 goto again;
750 default:
751 if (s < m)
752 *s++ = c;
753 break;
756 #endif
758 #endif
763 mntclose(void* handle)
765 register Handle_t* mp = (Handle_t*)handle;
767 if (!mp)
768 return -1;
769 sfclose(mp->fp);
770 free(mp);
771 return 0;
774 #endif
776 #endif
778 #endif
781 * currently no write
785 mntwrite(void* handle, const Mnt_t* mnt)
787 NoP(handle);
788 NoP(mnt);
789 return -1;
792 #endif