📄 net-submountd.c
字号:
/*************************************************************************** net-submountd.c ------------------- begin : Wed Nov 18 13:15 EDT 2003 copyright : (C) 2003-2004 by Eugene S. Weiss email : eweiss@sbcglobal.net ***************************************************************************//*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ /* This is part of the submount system. It is a lightweight * program for mounting and unmounting network filesystems * by calling the standard mount programs. * * net-submountd is an alternate client for the submount system. It * is intended for use for network filesystems, or other situations where * calling the kernel mount() system call is insufficient to create a mount. * It works by calling the standard /bin/mount and /bin/umount programs. It * accepts the option "interval=XX" to determin the frequency of attempts to * unmount the filesystem. Otherwise, the options and syntax */#include <stdio.h>#include <stdlib.h>#include <unistd.h>#include <syslog.h>#include <string.h>#include <sys/types.h>#include <sys/wait.h>#include <sys/stat.h>#include <sys/user.h>#include <sys/param.h>#include <fcntl.h>#include "submountd.h"#include "net-submountd.h"int do_umount(char *mountpoint){ pid_t pid; int status, numbytes; int pipefd[2]; char err_output[2048]; if(pipe(pipefd) != 0) exit(EXIT_FAILURE); pid = fork(); switch (pid) { case -1: close(pipefd[0]); close(pipefd[1]); return 1; case 0: dup2(pipefd[1], STDOUT_FILENO); dup2(pipefd[1], STDERR_FILENO); close(pipefd[0]); close(pipefd[1]); execl(STD_UMOUNT, STD_UMOUNT, mountpoint, NULL); exit(EXIT_FAILURE); default: break; } wait (&status); close(pipefd[1]); if(WIFEXITED(status)) { if(WEXITSTATUS(status)) { numbytes = read(pipefd[0], err_output, 2047); err_output[numbytes] = '\0'; close(pipefd[0]); if(strstr(err_output, "busy")) return -1; } close(pipefd[0]); return (WEXITSTATUS(status)); } close(pipefd[0]); return 1;}void umountd(char *device, char *mountpoint, char *fstype, int interval){ int retval, match; FILE *mntlist; char line[4096], fs[16], top[16], mntpt[4096 + 1]; for (;;) { sleep(interval); mntlist = fopen(MOUNT_LIST, "r"); if (!mntlist) continue; match = 0; while (fgets(line, sizeof(line), mntlist)) { sscanf(line, "%*s %4096s %15s", mntpt, fs); if (strcmp(mountpoint, mntpt) == 0) { strcpy(top, fs); match++; } } fclose(mntlist); if ((!match) || ((strncmp(fs, "subfs", 6) == 0) && (match < 3))) { exit(EXIT_SUCCESS); } if ((strcmp(fstype, fs) == 0) || (match > 2)) { retval = do_umount(mountpoint); if ((!retval) && (match < 3)) exit(EXIT_SUCCESS); if(retval > 0) /* Received error other than busy. */ exit(EXIT_FAILURE); } }}void launch_umountd(char *device, char *mountpoint, char *fstype, int interval){ pid_t pid; pid = fork(); switch (pid) { case -1: break; case 0: umountd(device, mountpoint, fstype, interval); default: break; } return;}char * addopt(const char *opt, char *optlist){ char *newoptlist; int len; if((len = strlen(optlist)) != 0) { if(!(newoptlist = malloc(len + strlen(opt) + 2))) exit(EXIT_FAILURE); strcpy(newoptlist, optlist); strcat(newoptlist, ","); strcat(newoptlist, opt); free(optlist); } else { if(!(newoptlist = malloc(strlen(opt) + 1))) exit(EXIT_FAILURE); strcpy(newoptlist, opt); } return newoptlist;}int do_mount(char *device, char *mountpoint, char *fstype, char *options){ pid_t pid; int status; pid = fork(); switch (pid) { case -1: return 1; case 0: execl(STD_MOUNT, STD_MOUNT, "-t", fstype, "-o", options, device, mountpoint, NULL); exit(EXIT_FAILURE); default: break; } wait (&status); if(WIFEXITED(status)) return WEXITSTATUS(status); return 1;}int main(int argc, char *argv[]){ struct mount_params p; char *optlist, *opt, *ptr; int interval = DEFAULT_INTERVAL, len; p.device = argv[1]; p.mountpoint = argv[2]; p.fstype = argv[3]; p.options = argv[5]; sscanf(argv[4], "%lx", &p.flags); if(!(optlist = malloc(strlen(p.options) + 1))) exit(EXIT_FAILURE); optlist[0] = '\0'; while ((opt = strsep(&p.options, ","))) { if ((ptr = strstr(opt, "interval="))) { sscanf((ptr + 9), "%d", &interval); } else { strcat(optlist, opt); strcat(optlist, ","); } } len = strlen(optlist); if((len != 0) && (optlist[len - 1] == ',')) optlist[len - 1] = '\0'; if (p.flags & MS_RDONLY) optlist = addopt ( "ro", optlist ); if (p.flags & MS_NOSUID) optlist = addopt ( "nosuid", optlist ); if (p.flags & MS_NODEV) optlist = addopt ( "nodev", optlist ); if (p.flags & MS_NOEXEC) optlist = addopt ( "noexec", optlist ); if (p.flags & MS_SYNCHRONOUS) optlist = addopt ( "sync", optlist ); if (p.flags & MS_MANDLOCK) optlist = addopt ( "mand", optlist ); if (p.flags & MS_DIRSYNC) optlist = addopt ( "dirsync", optlist ); if (p.flags & MS_NOATIME) optlist = addopt ( "noatime", optlist ); if (p.flags & MS_NODIRATIME) optlist = addopt ( "nodiratime", optlist ); if (do_mount(p.device, p.mountpoint, p.fstype, optlist)) exit(EXIT_FAILURE); launch_umountd(p.device, p.mountpoint, p.fstype, interval); exit(EXIT_SUCCESS);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -