00001
00002
00003 #include <errno.h>
00004 #include <sys/types.h>
00005 #include <limits.h>
00006 #include <stdlib.h>
00007 #include <dirent.h>
00008 #include <string.h>
00009 #include <unistd.h>
00010 #include <fcntl.h>
00011 #include <minix/config.h>
00012 #include <minix/const.h>
00013 #include <minix/minlib.h>
00014 #include <minix/swap.h>
00015 #include <sys/svrctl.h>
00016 #include <stdio.h>
00017 #include "../../servers/fs/const.h"
00018
00019 _PROTOTYPE(int main, (int argc, char **argv));
00020 _PROTOTYPE(void list, (void));
00021 _PROTOTYPE(void usage, (void));
00022 _PROTOTYPE(void tell, (char *this));
00023 _PROTOTYPE(void swapon, (char *file));
00024
00025 static u8_t MAGIC[] = { SWAP_MAGIC0, SWAP_MAGIC1, SWAP_MAGIC2, SWAP_MAGIC3 };
00026
00027 int main(argc, argv)
00028 int argc;
00029 char *argv[];
00030 {
00031 int i, ro, swap, n, v;
00032 char **ap, *vs, *opt, *err;
00033 char special[PATH_MAX+1], mounted_on[PATH_MAX+1], version[10], rw_flag[10];
00034
00035 if (argc == 1) list();
00036 ro = 0;
00037 swap = 0;
00038 ap = argv+1;
00039 for (i = 1; i < argc; i++) {
00040 if (argv[i][0] == '-') {
00041 opt = argv[i]+1;
00042 while (*opt != 0) switch (*opt++) {
00043 case 'r': ro = 1; break;
00044 case 's': swap = 1; break;
00045 default: usage();
00046 }
00047 } else {
00048 *ap++ = argv[i];
00049 }
00050 }
00051 *ap = NULL;
00052 argc = (ap - argv);
00053
00054 if (ro && swap) usage();
00055
00056 if (swap) {
00057 if (argc != 2) usage();
00058 swapon(argv[1]);
00059 tell(argv[1]);
00060 tell(" is swapspace\n");
00061 } else {
00062 if (argc != 3) usage();
00063 if (mount(argv[1], argv[2], ro) < 0) {
00064 err = strerror(errno);
00065 std_err("mount: Can't mount ");
00066 std_err(argv[1]);
00067 std_err(" on ");
00068 std_err(argv[2]);
00069 std_err(": ");
00070 std_err(err);
00071 std_err("\n");
00072 exit(1);
00073 }
00074
00075 tell(argv[1]);
00076 tell(" is read-");
00077 tell(ro ? "only" : "write");
00078 tell(" mounted on ");
00079 tell(argv[2]);
00080 tell("\n");
00081 }
00082
00083
00084 n = load_mtab("mount");
00085 if (n < 0) exit(1);
00086
00087
00088 while (1) {
00089 n = get_mtab_entry(special, mounted_on, version, rw_flag);
00090 if (n < 0) break;
00091 n = put_mtab_entry(special, mounted_on, version, rw_flag);
00092 if (n < 0) {
00093 std_err("mount: /etc/mtab has grown too large\n");
00094 exit(1);
00095 }
00096 }
00097 if (swap) {
00098 vs = "swap";
00099 } else {
00100 v = fsversion(argv[1], "mount");
00101 if (v == 1)
00102 vs = "1";
00103 else if (v == 2)
00104 vs = "2";
00105 else if (v == 3)
00106 vs = "3";
00107 else
00108 vs = "0";
00109 }
00110 n = put_mtab_entry(argv[1], swap ? "swap" : argv[2], vs, (ro ? "ro" : "rw") );
00111 if (n < 0) {
00112 std_err("mount: /etc/mtab has grown too large\n");
00113 exit(1);
00114 }
00115
00116 n = rewrite_mtab("mount");
00117 return(0);
00118 }
00119
00120
00121 void list()
00122 {
00123 int n;
00124 char special[PATH_MAX+1], mounted_on[PATH_MAX+1], version[10], rw_flag[10];
00125
00126
00127 n = load_mtab("mount");
00128 if (n < 0) exit(1);
00129
00130 while (1) {
00131 n = get_mtab_entry(special, mounted_on, version, rw_flag);
00132 if (n < 0) break;
00133 write(1, special, strlen(special));
00134 if (strcmp(version, "swap") == 0) {
00135 tell(" is swapspace\n");
00136 } else {
00137 tell(" is read-");
00138 tell(strcmp(rw_flag, "rw") == 0 ? "write" : "only");
00139 tell(" mounted on ");
00140 tell(mounted_on);
00141 tell("\n");
00142 }
00143 }
00144 exit(0);
00145 }
00146
00147
00148 void usage()
00149 {
00150 std_err("Usage: mount [-r] special name\n mount -s special\n");
00151 exit(1);
00152 }
00153
00154
00155 void tell(this)
00156 char *this;
00157 {
00158 write(1, this, strlen(this));
00159 }
00160
00161 void swapon(file)
00162 char *file;
00163 {
00164 u32_t super[2][_MAX_BLOCK_SIZE / 2 / sizeof(u32_t)];
00165 swap_hdr_t *sp;
00166 struct mmswapon mmswapon;
00167 int fd, r;
00168 char *err;
00169
00170 if ((fd = open(file, O_RDWR)) < 0
00171 || lseek(fd, SUPER_BLOCK_BYTES, SEEK_SET) == -1
00172 || (r = read(fd, super, _STATIC_BLOCK_SIZE)) < 0
00173 ) {
00174 err = strerror(errno);
00175 std_err("mount: ");
00176 std_err(file);
00177 std_err(": ");
00178 std_err(err);
00179 std_err("\n");
00180 exit(1);
00181 }
00182 sp = (swap_hdr_t *) &super[0];
00183 if (memcmp(sp->sh_magic, MAGIC, sizeof(MAGIC)) != 0)
00184 sp = (swap_hdr_t *) &super[1];
00185 if (r == _STATIC_BLOCK_SIZE && memcmp(sp->sh_magic, MAGIC, sizeof(MAGIC)) != 0
00186 || sp->sh_version > SH_VERSION) {
00187 std_err("mount: ");
00188 std_err(file);
00189 std_err(" is not swapspace\n");
00190 exit(1);
00191 }
00192 close(fd);
00193 mmswapon.offset = sp->sh_offset;
00194 mmswapon.size = sp->sh_swapsize;
00195 strncpy(mmswapon.file, file, sizeof(mmswapon.file));
00196 mmswapon.file[sizeof(mmswapon.file)-1] = 0;
00197 if (svrctl(MMSWAPON, &mmswapon) < 0) {
00198 err = strerror(errno);
00199 std_err("mount: ");
00200 std_err(file);
00201 std_err(": ");
00202 std_err(err);
00203 std_err("\n");
00204 exit(1);
00205 }
00206 }