1c2808d8bSBen Gras /* This package consists of 4 routines for handling the /etc/mtab file.
2c2808d8bSBen Gras * The /etc/mtab file contains information about the root and mounted file
3c2808d8bSBen Gras * systems as a series of lines, each one with exactly four fields separated
4c2808d8bSBen Gras * by one space as follows:
5c2808d8bSBen Gras *
6c2808d8bSBen Gras * special mounted_on version rw_flag
7c2808d8bSBen Gras *
8c2808d8bSBen Gras * where
9c2808d8bSBen Gras * special is the name of the block special file
10c2808d8bSBen Gras * mounted_on is the directory on which it is mounted
11c2808d8bSBen Gras * version is either 1 or 2 for MINIX V1 and V2 file systems
12c2808d8bSBen Gras * rw_flag is rw or ro for read/write or read only
13c2808d8bSBen Gras *
14c2808d8bSBen Gras * An example /etc/mtab:
15c2808d8bSBen Gras *
16c2808d8bSBen Gras * /dev/ram / 2 rw
17c2808d8bSBen Gras * /dev/hd1 /usr 2 rw
18c2808d8bSBen Gras * /dev/fd0 /user 1 ro
19c2808d8bSBen Gras *
20c2808d8bSBen Gras *
21c2808d8bSBen Gras * The four routines for handling /etc/mtab are as follows. They use two
22c2808d8bSBen Gras * (hidden) internal buffers, mtab_in for input and mtab_out for output.
23c2808d8bSBen Gras *
24c2808d8bSBen Gras * load_mtab(&prog_name) - read /etc/mtab into mtab_in
25c2808d8bSBen Gras * get_mtab_entry(&s1, &s2, &s3, &s4) - arrays that are filled in
26c2808d8bSBen Gras *
27c2808d8bSBen Gras * If load_mtab works, it returns 0. If it fails, it prints its own error
28c2808d8bSBen Gras * message on stderr and returns -1. When get_mtab_entry
29c2808d8bSBen Gras * runs out of entries to return, it sets the first pointer to NULL and returns
30c2808d8bSBen Gras * -1 instead of 0.
31c2808d8bSBen Gras */
32c2808d8bSBen Gras
33c2808d8bSBen Gras #include <sys/types.h>
34c2808d8bSBen Gras #include <lib.h>
35c2808d8bSBen Gras #include <minix/minlib.h>
36c2808d8bSBen Gras #include <ctype.h>
37c2808d8bSBen Gras #include <fcntl.h>
38c2808d8bSBen Gras #include <stdlib.h>
39c2808d8bSBen Gras #include <string.h>
40c2808d8bSBen Gras #include <unistd.h>
41c2808d8bSBen Gras #include <stdio.h>
42c2808d8bSBen Gras
43c2808d8bSBen Gras #define BUF_SIZE 512 /* size of the /etc/mtab buffer */
44c2808d8bSBen Gras
45*5dd8da10SDavid van Moolenbroek const char *etc_mtab = "/etc/mtab"; /* name of the /etc/mtab file */
46c2808d8bSBen Gras static char mtab_in[BUF_SIZE+1]; /* holds /etc/mtab when it is read in */
47c2808d8bSBen Gras static char *iptr = mtab_in; /* pointer to next line to feed out. */
48c2808d8bSBen Gras
49c2808d8bSBen Gras int load_mtab(char *prog_name);
50c2808d8bSBen Gras int get_mtab_entry(char dev[PATH_MAX], char mount_point[PATH_MAX],
51c2808d8bSBen Gras char type[MNTNAMELEN], char flags[MNTFLAGLEN]);
52c2808d8bSBen Gras static void err(char *prog_name, const char *str);
53c2808d8bSBen Gras
54c2808d8bSBen Gras
load_mtab(char * prog_name)55c2808d8bSBen Gras int load_mtab(char *prog_name)
56c2808d8bSBen Gras {
57c2808d8bSBen Gras /* Read in /etc/mtab and store it in /etc/mtab. */
58c2808d8bSBen Gras
59c2808d8bSBen Gras int fd, n;
60c2808d8bSBen Gras char *ptr;
61c2808d8bSBen Gras
62c2808d8bSBen Gras /* Open the file. */
63c2808d8bSBen Gras fd = open(etc_mtab, O_RDONLY);
64c2808d8bSBen Gras if (fd < 0) {
65c2808d8bSBen Gras err(prog_name, ": cannot open ");
66c2808d8bSBen Gras return(-1);
67c2808d8bSBen Gras }
68c2808d8bSBen Gras
69c2808d8bSBen Gras /* File opened. Read it in. */
70c2808d8bSBen Gras n = read(fd, mtab_in, BUF_SIZE);
71c2808d8bSBen Gras if (n <= 0) {
72c2808d8bSBen Gras /* Read failed. */
73c2808d8bSBen Gras err(prog_name, ": cannot read ");
74c2808d8bSBen Gras return(-1);
75c2808d8bSBen Gras }
76c2808d8bSBen Gras if (n == BUF_SIZE) {
77c2808d8bSBen Gras /* Some nut has mounted 50 file systems or something like that. */
78c2808d8bSBen Gras std_err(prog_name);
79c2808d8bSBen Gras std_err(": file too large: ");
80c2808d8bSBen Gras std_err(etc_mtab);
81c2808d8bSBen Gras return(-1);
82c2808d8bSBen Gras }
83c2808d8bSBen Gras
84c2808d8bSBen Gras close(fd);
85c2808d8bSBen Gras
86c2808d8bSBen Gras ptr = mtab_in;
87c2808d8bSBen Gras
88c2808d8bSBen Gras return(0);
89c2808d8bSBen Gras }
90c2808d8bSBen Gras
get_mtab_entry(char dev[PATH_MAX],char mount_point[PATH_MAX],char type[MNTNAMELEN],char flags[MNTFLAGLEN])91c2808d8bSBen Gras int get_mtab_entry(char dev[PATH_MAX], char mount_point[PATH_MAX],
92c2808d8bSBen Gras char type[MNTNAMELEN], char flags[MNTFLAGLEN])
93c2808d8bSBen Gras {
94c2808d8bSBen Gras /* Return the next entry from mtab_in. */
95c2808d8bSBen Gras
96c2808d8bSBen Gras int r;
97c2808d8bSBen Gras
98c2808d8bSBen Gras if (iptr >= &mtab_in[BUF_SIZE]) {
99c2808d8bSBen Gras dev[0] = '\0';
100c2808d8bSBen Gras return(-1);
101c2808d8bSBen Gras }
102c2808d8bSBen Gras
103c2808d8bSBen Gras r = sscanf(iptr, "%s on %s type %s (%[^)]s\n",
104c2808d8bSBen Gras dev, mount_point, type, flags);
105c2808d8bSBen Gras if (r != 4) {
106c2808d8bSBen Gras dev[0] = '\0';
107c2808d8bSBen Gras return(-1);
108c2808d8bSBen Gras }
109c2808d8bSBen Gras
110c2808d8bSBen Gras iptr = strchr(iptr, '\n'); /* Find end of line */
111c2808d8bSBen Gras if (iptr != NULL) iptr++; /* Move to next line */
112c2808d8bSBen Gras return(0);
113c2808d8bSBen Gras
114c2808d8bSBen Gras }
115c2808d8bSBen Gras
err(char * prog_name,const char * str)116c2808d8bSBen Gras static void err(char *prog_name, const char *str)
117c2808d8bSBen Gras {
118c2808d8bSBen Gras std_err(prog_name);
119c2808d8bSBen Gras std_err(str);
120c2808d8bSBen Gras std_err(etc_mtab);
121c2808d8bSBen Gras perror(" ");
122c2808d8bSBen Gras }
123