/* umount - unmount a file system Author: Andy Tanenbaum */ /* 06/13/1994 - Claudio Tantignone. Modification to take block device or moount point via convertion with mtab table. 09/14/2000 - Claudio Tantignone. Solve pointer compilation with strstr() function under Minix 2.0.2 */ /* Compile as: # cc -wa -o umount umount.c # chmem =32768 umount */ #define _POSIX_SOURCE #define _MINIX /* #define DEBUG */ #include #include #include #include #define BUFSIZE 1024 #define NOCONVERT 0 #define CONVERT 1 #define BAD 2 extern int errno; extern char *strchr(); char *mounttable = "/etc/mtab"; char buffer[BUFSIZE], *p = &buffer[0], *q; char dev[BUFSIZE]; /* device to be unmounted */ main(argc, argv) int argc; char *argv[]; { int flag = NOCONVERT; /* flag to print convertion */ if (argc != 2) usage(); flag = parse(argv[1],dev); /* parse device name or mount point */ if (flag == BAD) { std_err(argv[1]); std_err(" : invalid umount point\n"); exit(EINVAL); } #ifdef DEBUG printf("parse device is %s\n", dev); #endif if (umount(dev) < 0) { if (errno == EINVAL) std_err("Device not mounted\n"); else perror("umount"); exit(errno); } std_err(argv[1]); if (flag) { /* check if is necesary to print more info */ std_err(" ("); std_err(dev); std_err(")"); } std_err(" unmounted\n"); do_mtab(dev); exit(0); } do_mtab(devname) char *devname; { /* Remove an entry from mtab. */ int n, fd; char line[256]; p = &buffer[0]; /* Read in the mount table and then overwrite the file. */ fd = open(mounttable, O_RDWR); n = read(fd, buffer, BUFSIZE); close(fd); q = &buffer[n]; fd = creat(mounttable, 0554); n = strlen(devname); while (getline(line) != 0) { if (strncmp(line, devname, n) == 0) continue; write(fd, line, strlen(line)); } } int getline(ptr) char *ptr; { char c; while (p < q) { c = *p++; *ptr++ = c; if (c == '\n') { *ptr++ = 0; return(1); } } return(0); } usage() { std_err("Usage: umount special [mount-point]\n"); exit(1); } parse(in,out) /* parse mount point or device to device */ char *in; /* device or mount point to be umounted */ char *out; /* physical device to be umounted */ { struct stat st; /* device struct */ int n, fd, s, l; char line[256]; #ifdef DEBUG printf("stat for file %s\n", in); #endif if (stat(in,&st) == -1) { perror("stat"); exit(errno); } #ifdef DEBUG printf("check mode for %s, mode %o \n", in,st.st_mode); #endif if ((st.st_mode&S_IFBLK) == S_IFBLK) { /* if directly give device */ #ifdef DEBUG printf("%s is block device \n", in); #endif strcpy(out,in); /* copy device name and return */ return(NOCONVERT); } /* here must check into mtab to convert mount point to device */ /* Read in the mount table */ #ifdef DEBUG printf("reading mtab ...\n"); #endif fd = open(mounttable, O_RDONLY); n = read(fd, buffer, BUFSIZE); close(fd); q = &buffer[n]; n = strlen(in); s = BAD; #ifdef DEBUG printf("searching for %s ...\n",in); #endif while (getline(line) != 0) { #ifdef DEBUG printf("line : %s",line); #endif l = strlen(line); /* if (strstr(line, in) != ((char *) 0)) { */ if (strstr(line, in) != 0) { #ifdef DEBUG printf("%s founded in mtab.\n",in); #endif s = CONVERT; /* take from origin of line the device name and copy it */ q = strchr(line,(int)' '); /* get end position */ *q = '\0'; strcpy(out,line); break; } } return(s); }